package com.southminority.ethnic.service.research.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.southminority.ethnic.common.exception.BusinessException;
import com.southminority.ethnic.common.result.PageResult;
import com.southminority.ethnic.mapper.research.AwardMapper;
import com.southminority.ethnic.pojo.Award;
import com.southminority.ethnic.service.research.AwardService;
import com.southminority.ethnic.controller.research.vo.AwardVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 获奖情况服务实现类.
 * <p>
 * 实现了 {@link AwardService} 接口，负责处理所有与获奖情况相关的业务逻辑。
 * 包括数据查询、转换、增删改查等操作，并处理了JSON格式字段的序列化与反序列化。
 * 
 * @author SouthMinority
 */
@Slf4j
@Service
@Transactional
public class AwardServiceImpl implements AwardService {

    private final AwardMapper awardMapper;
    private final ObjectMapper objectMapper;

    public AwardServiceImpl(AwardMapper awardMapper, ObjectMapper objectMapper) {
        this.awardMapper = awardMapper;
        this.objectMapper = objectMapper;
    }

    // =================================================================================
    // ==                             前端展示相关方法 (Public API)                     ==
    // =================================================================================

    @Override
    public PageResult<AwardVO> getPublishedAwardPage(Integer page, Integer size, Integer year, String level, String category) {
        Page<Award> pageObj = new Page<>(page, size);
        QueryWrapper<Award> wrapper = new QueryWrapper<>();

        wrapper.eq("status", 1);

        if (year != null) {
            wrapper.eq("award_year", year);
        }
        if (StringUtils.hasText(level)) {
            wrapper.eq("award_level", level);
        }
        if (StringUtils.hasText(category)) {
            wrapper.eq("award_category", category);
        }

        wrapper.orderByDesc("is_featured")
               .orderByDesc("award_year")
               .orderByAsc("sort_order");

        IPage<Award> pageResult = awardMapper.selectPage(pageObj, wrapper);
        List<AwardVO> voList = pageResult.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return PageResult.<AwardVO>builder()
                .current(pageResult.getCurrent())
                .size(pageResult.getSize())
                .total(pageResult.getTotal())
                .pages(pageResult.getPages())
                .records(voList)
                .build();
    }

    @Override
    public AwardVO getAwardDetail(Long id) {
        Award award = awardMapper.selectById(id);
        if (award == null || award.getStatus() != 1) {
            throw new BusinessException("获奖记录不存在或未发布");
        }
        return convertToVO(award);
    }

    @Override
    public List<Integer> getAwardYears() {
        QueryWrapper<Award> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT award_year")
               .eq("status", 1)
               .isNotNull("award_year")
               .orderByDesc("award_year");
        
        return awardMapper.selectList(wrapper).stream()
                          .map(Award::getAwardYear)
                          .collect(Collectors.toList());
    }

    @Override
    public List<String> getAwardLevels() {
        QueryWrapper<Award> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT award_level")
               .eq("status", 1)
               .isNotNull("award_level")
               .orderByAsc("award_level");
        
        return awardMapper.selectList(wrapper).stream()
                          .map(Award::getAwardLevel)
                          .filter(StringUtils::hasText)
                          .collect(Collectors.toList());
    }

    @Override
    public List<String> getAwardCategories() {
        QueryWrapper<Award> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT award_category")
               .eq("status", 1)
               .isNotNull("award_category")
               .orderByAsc("award_category");
        
        return awardMapper.selectList(wrapper).stream()
                          .map(Award::getAwardCategory)
                          .filter(StringUtils::hasText)
                          .collect(Collectors.toList());
    }


    // =================================================================================
    // ==                             后台管理相关方法 (Admin API)                      ==
    // =================================================================================

    @Override
    public PageResult<AwardVO> getAwardPageForAdmin(Integer page, Integer size, String keyword, String category, String level, Integer status) {
        Page<Award> pageObj = new Page<>(page, size);
        QueryWrapper<Award> wrapper = new QueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.and(qw -> qw.like("title", keyword)
                               .or().like("project_name", keyword));
        }
        if (StringUtils.hasText(category)) {
            wrapper.eq("award_category", category);
        }
        if (StringUtils.hasText(level)) {
            wrapper.eq("award_level", level);
        }
        if (status != null) {
            wrapper.eq("status", status);
        } else {
            wrapper.ne("status", -1);
        }
        
        wrapper.orderByDesc("is_featured")
               .orderByDesc("award_year")
               .orderByAsc("sort_order");
        
        IPage<Award> pageResult = awardMapper.selectPage(pageObj, wrapper);
        List<AwardVO> voList = pageResult.getRecords().stream()
                                        .map(this::convertToVO)
                                        .collect(Collectors.toList());
        
        return PageResult.<AwardVO>builder()
                .current(pageResult.getCurrent())
                .size(pageResult.getSize())
                .total(pageResult.getTotal())
                .pages(pageResult.getPages())
                .records(voList)
                .build();
    }

    @Override
    public AwardVO getAwardDetailForAdmin(Long id) {
        Award award = awardMapper.selectById(id);
        if (award == null) {
            throw new BusinessException("获奖记录不存在");
        }
        return convertToVO(award);
    }

    @Override
    public AwardVO createAward(Award award) {
        if (award == null) {
            throw new BusinessException("获奖信息不能为空");
        }
        award.setCreateTime(LocalDateTime.now());
        award.setUpdateTime(LocalDateTime.now());
        awardMapper.insert(award);
        return convertToVO(award);
    }

    @Override
    public AwardVO updateAward(Long id, Award award) {
        Award existingAward = awardMapper.selectById(id);
        if (existingAward == null) {
            throw new BusinessException("获奖记录不存在");
        }
        
        award.setId(id);
        award.setUpdateTime(LocalDateTime.now());
        awardMapper.updateById(award);
        return convertToVO(awardMapper.selectById(id));
    }

    @Override
    public boolean deleteAward(Long id) {
        Award award = awardMapper.selectById(id);
        if (award == null) {
            return true;
        }
        
        award.setStatus(-1);
        award.setUpdateTime(LocalDateTime.now());
        return awardMapper.updateById(award) > 0;
    }

    @Override
    public boolean batchDeleteAwards(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("ID列表不能为空");
        }
        
        List<Award> awardList = awardMapper.selectBatchIds(ids);
        if (awardList.isEmpty()) {
            return true;
        }
        
        LocalDateTime now = LocalDateTime.now();
        for (Award award : awardList) {
            award.setStatus(-1);
            award.setUpdateTime(now);
            awardMapper.updateById(award);
        }
        
        return true;
    }

    @Override
    public boolean updateAwardStatus(Long id, Integer status) {
        Award award = awardMapper.selectById(id);
        if (award == null) {
            throw new BusinessException("获奖记录不存在");
        }
        if (status == null || (status < -1 || status > 1)) {
            throw new BusinessException("无效的状态值");
        }
        
        award.setStatus(status);
        award.setUpdateTime(LocalDateTime.now());
        return awardMapper.updateById(award) > 0;
    }

    @Override
    public boolean setAwardFeatured(Long id, Integer isFeatured) {
        Award award = awardMapper.selectById(id);
        if (award == null) {
            throw new BusinessException("获奖记录不存在");
        }
        if (isFeatured == null || (isFeatured != 0 && isFeatured != 1)) {
            throw new BusinessException("无效的置顶值");
        }
        
        award.setIsFeatured(isFeatured);
        award.setUpdateTime(LocalDateTime.now());
        return awardMapper.updateById(award) > 0;
    }

    // =================================================================================
    // ==                             私有辅助方法 (Private Helpers)                      ==
    // =================================================================================

    /**
     * 将 Award POJO 转换为 AwardVO DTO.
     * <p>
     * 此方法负责处理复杂数据类型的转换，例如将数据库中存储的JSON字符串
     * 转换为Java的List，以便前端可以直接使用。
     *
     * @param award 数据库实体对象
     * @return 用于前端展示的视图对象
     */
    private AwardVO convertToVO(Award award) {
        if (award == null) return null;
        
        AwardVO vo = new AwardVO();
        BeanUtils.copyProperties(award, vo);
        
        try {
            if (StringUtils.hasText(award.getRecipients())) {
                vo.setRecipients(objectMapper.readValue(award.getRecipients(), new TypeReference<List<String>>() {}));
            } else {
                vo.setRecipients(Collections.emptyList());
            }
            
            if (StringUtils.hasText(award.getPhotoUrls())) {
                vo.setPhotoUrls(objectMapper.readValue(award.getPhotoUrls(), new TypeReference<List<String>>() {}));
            } else {
                vo.setPhotoUrls(Collections.emptyList());
            }
        } catch (JsonProcessingException e) {
            log.error("解析获奖(ID:{})的JSON字段失败: {}", award.getId(), e.getMessage());
            vo.setRecipients(Collections.emptyList());
            vo.setPhotoUrls(Collections.emptyList());
        }
        
        return vo;
    }
} 
